package com.swift.violent.mainstay.config.data.source.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * 核心数据源配置
 * The type Default data source manager.
 *
 * @author xuhaifeng
 * @date 2021.1.19 21:02
 */
@Slf4j
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
@MapperScan(basePackages = "com.swift.violent.mainstay.core.base.core.dao.mapper", sqlSessionTemplateRef = "baseSqlSessionTemplate")
public class BaseDataSourceConfig {
    private static final String MAPPER_LOCATION = "classpath*:mapper/base/*.xml";

    /**
     * 核心数据源
     *
     * @return the data source
     */
    @Primary
    @Bean(name = "base")
    @Qualifier(value = "base")
    @ConfigurationProperties("spring.datasource.base")
    public DataSource base() {
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * 核心数据源会话工厂
     *
     * @param dataSource the data source
     *
     * @return the sql session factory
     */
    @Primary
    @SneakyThrows
    @Bean(name = "baseSqlSessionFactory")
    public SqlSessionFactory baseSqlSessionFactory(@Qualifier("base") DataSource dataSource) {
        final MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
        return bean.getObject();
    }

    /**
     * 核心数据源事务管理器
     *
     * @param dataSource the data source
     *
     * @return the data source transaction manager
     */
    @Primary
    @Bean(name = "baseTransactionManger")
    public DataSourceTransactionManager baseTransactionManger(@Qualifier("base") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    /**
     * 核心数据源SQL会话模板
     *
     * @param sqlSessionFactory the sql session factory
     *
     * @return the sql session template
     */
    @Primary
    @Bean(name = "baseSqlSessionTemplate")
    public SqlSessionTemplate baseSqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    /**
     * JdbcTemplate 关联核心数据源
     *
     * @param dataSource the data source
     *
     * @return the jdbc template
     */
    @Primary
    @Bean(name = "jdbcTemplateBase")
    public JdbcTemplate jdbcTemplateBase(@Qualifier(value = "base") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

}